package com.xyzwps.orm.ormlite.repository;

import com.j256.ormlite.dao.Dao;
import com.xyzwps.orm.exception.TagDuplicateException;
import com.xyzwps.orm.model.Tag;
import com.xyzwps.orm.repository.TagRepository;
import com.xyzwps.orm.util.ExceptionUtils;

import java.sql.SQLException;
import java.sql.SQLIntegrityConstraintViolationException;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

public class OrmLiteTagRepository implements TagRepository {

    private final Dao<Tag, Integer> tagDao;

    public OrmLiteTagRepository(Dao<Tag, Integer> tagDao) {
        this.tagDao = Objects.requireNonNull(tagDao);
    }

    @Override
    public int insert(Tag tag) {
        try {
            tagDao.create(tag);
            return tag.getTagId();
        } catch (SQLException ex) {
            if (ExceptionUtils.causedBy(ex, SQLIntegrityConstraintViolationException.class)) {
                throw new TagDuplicateException(tag.getTagName());
            } else {
                throw new IllegalStateException(ex);
            }
        }
    }

    @Override
    public void update(Tag tag) {
        try {
            tagDao.update(tag);
        } catch (SQLException ex) {
            if (ExceptionUtils.causedBy(ex, SQLIntegrityConstraintViolationException.class)) {
                throw new TagDuplicateException(tag.getTagName());
            } else {
                throw new IllegalStateException(ex);
            }
        }
    }

    @Override
    public void delete(int tagId) {
        try {
            tagDao.deleteById(tagId);
        } catch (SQLException ex) {
            throw new IllegalStateException(ex);
        }
    }

    @Override
    public Optional<Tag> selectByTagId(int tagId) {
        try {
            return Optional.ofNullable(tagDao.queryForId(tagId));
        } catch (SQLException ex) {
            throw new IllegalStateException(ex);
        }
    }

    @Override
    public List<Tag> selectAllForUser(int userId) {
        try {
            var builder = tagDao.queryBuilder();
            var where = builder.where();
            where.eq("user_id", userId);
            return where.query();
        } catch (SQLException ex) {
            throw new IllegalStateException(ex);
        }
    }

}
